home *** CD-ROM | disk | FTP | other *** search
/ Programming an RTS Game with Direct3D / Programming an RTS Game with Direct3D.iso / Examples / Chapter 10 / Example 10.1 / mapObject.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2006-06-30  |  6.5 KB  |  221 lines

  1. #include "mapObject.h"
  2. #include "unit.h"
  3.  
  4. //Line interface to draw selected units/buildings with
  5. ID3DXLine *line = NULL;
  6.  
  7. //variables used for fog-of-war
  8. IDirect3DTexture9* sightTexture = NULL;
  9. ID3DXMesh *sightMesh = NULL;
  10. D3DMATERIAL9 sightMtrl;
  11.  
  12. struct SIGHTVertex
  13. {
  14.     SIGHTVertex(){}
  15.     SIGHTVertex(D3DXVECTOR3 pos, D3DXVECTOR2 _uv)
  16.     {
  17.         position = pos;
  18.         uv = _uv;
  19.     }
  20.  
  21.     D3DXVECTOR3 position;
  22.     D3DXVECTOR2 uv;
  23.  
  24.     static const DWORD FVF;
  25. };
  26.  
  27. const DWORD SIGHTVertex::FVF = D3DFVF_XYZ | D3DFVF_TEX1;
  28.  
  29. void LoadMapObjectResources(IDirect3DDevice9* Device)
  30. {
  31.     D3DXCreateLine(Device, &line);
  32.  
  33.     //Sight texture
  34.     Device->CreateTexture(64, 64, 1, D3DUSAGE_DYNAMIC, D3DFMT_L8, D3DPOOL_DEFAULT, &sightTexture, NULL);
  35.  
  36.     D3DLOCKED_RECT sRect;
  37.     sightTexture->LockRect(0, &sRect, NULL, NULL);
  38.     BYTE *bytes = (BYTE*)sRect.pBits;
  39.     memset(bytes, 0, sRect.Pitch*sRect.Pitch);
  40.     
  41.     float intensity = 1.3f;
  42.     D3DXVECTOR2 center = D3DXVECTOR2(32.0f, 32.0f);
  43.     
  44.     for(int y=0;y<64;y++)
  45.         for(int x=0;x<64;x++)
  46.         {                        
  47.             float d = D3DXVec2Length(&(center - D3DXVECTOR2(x,y)));
  48.             int value = ((32.0f - d) / 32.0f) * 255.0f * intensity;
  49.             if(value < 0)value = 0;
  50.             if(value > 255)value = 255;
  51.             bytes[x + y * sRect.Pitch] = value;
  52.         }
  53.     sightTexture->UnlockRect(0);
  54.  
  55.     //D3DXSaveTextureToFile("sightTexture.bmp", D3DXIFF_BMP, sightTexture, NULL);
  56.  
  57.     //Calculate sight mesh (a simple quad)
  58.     D3DXCreateMeshFVF(2, 4, D3DXMESH_MANAGED, SIGHTVertex::FVF, Device, &sightMesh);
  59.  
  60.     //Create 4 vertices
  61.     SIGHTVertex* v = 0;
  62.     sightMesh->LockVertexBuffer(0,(void**)&v);
  63.     v[0] = SIGHTVertex(D3DXVECTOR3(-1, 0, 1),  D3DXVECTOR2(0, 0));
  64.     v[1] = SIGHTVertex(D3DXVECTOR3( 1, 0, 1),  D3DXVECTOR2(1, 0));
  65.     v[2] = SIGHTVertex(D3DXVECTOR3(-1, 0, -1), D3DXVECTOR2(0, 1));
  66.     v[3] = SIGHTVertex(D3DXVECTOR3( 1, 0, -1), D3DXVECTOR2(1, 1));
  67.     sightMesh->UnlockVertexBuffer();
  68.  
  69.     //Create 2 faces
  70.     WORD* indices = 0;
  71.     sightMesh->LockIndexBuffer(0,(void**)&indices);    
  72.     indices[0] = 0; indices[1] = 1; indices[2] = 2;
  73.     indices[3] = 1; indices[4] = 3; indices[5] = 2;
  74.     sightMesh->UnlockIndexBuffer();
  75.  
  76.     //Set Attributes for the 2 faces
  77.     DWORD *att = 0;
  78.     sightMesh->LockAttributeBuffer(0,&att);
  79.     att[0] = 0; att[1] = 0;
  80.     sightMesh->UnlockAttributeBuffer();
  81.  
  82.     //Sight MTRL
  83.     memset(&sightMtrl, 0, sizeof(D3DMATERIAL9));
  84.     sightMtrl.Diffuse = sightMtrl.Ambient = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
  85. }
  86.  
  87. void UnloadMapObjectResources()
  88. {
  89.     if(line)line->Release();
  90.     line = NULL;
  91.  
  92.     if(sightTexture)sightTexture->Release();
  93.     sightTexture = NULL;
  94.  
  95.     if(sightMesh)sightMesh->Release();
  96.     sightMesh = NULL;
  97. }
  98.  
  99. INTPOINT GetScreenPos(D3DXVECTOR3 pos, IDirect3DDevice9* Device)
  100. {
  101.     D3DXVECTOR3 screenPos;
  102.     D3DVIEWPORT9 Viewport;
  103.     D3DXMATRIX Projection, View, World;
  104.  
  105.     Device->GetViewport(&Viewport);
  106.     Device->GetTransform(D3DTS_VIEW, &View);
  107.     Device->GetTransform(D3DTS_PROJECTION, &Projection);
  108.     D3DXMatrixIdentity(&World);
  109.     D3DXVec3Project(&screenPos, &pos, &Viewport, &Projection, &View, &World);
  110.  
  111.     return INTPOINT(screenPos.x, screenPos.y);
  112. }
  113.  
  114. //////////////////////////////////////////////////////////////////////////////////
  115. //                                MapObject                                        //
  116. //////////////////////////////////////////////////////////////////////////////////
  117.  
  118. MAPOBJECT::MAPOBJECT()
  119. {
  120.     //Sets all variables to 0, NULL or False
  121.     m_isBuilding = false;
  122.     m_pTerrain = NULL;
  123.     m_hp = m_hpMax = 0;
  124.     m_range = m_damage = 0;
  125.     m_sightRadius = 0.0f;
  126.     m_team = m_type = 0;
  127.     m_selected = m_dead = m_visible = false;
  128.     m_pTarget = NULL;
  129.     m_pDevice = NULL;
  130. }
  131.  
  132. RECT MAPOBJECT::GetMapRect(int border)
  133. {
  134.     RECT mr = {m_mappos.x - border, 
  135.                m_mappos.y - border,
  136.                m_mappos.x + m_mapsize.x + border,
  137.                m_mappos.y + m_mapsize.y + border};
  138.  
  139.     return mr;
  140. }
  141.  
  142. void MAPOBJECT::PaintSelected()
  143. {
  144.     if(!m_selected || m_pDevice == NULL)return;
  145.  
  146.     BBOX bbox = GetBoundingBox();    //Bounding box in world space
  147.  
  148.     // Create 8 points according to the corners of the bounding box
  149.     D3DXVECTOR3 corners[] = {D3DXVECTOR3(bbox.max.x, bbox.max.y, bbox.max.z), 
  150.                              D3DXVECTOR3(bbox.max.x, bbox.max.y, bbox.min.z),
  151.                              D3DXVECTOR3(bbox.max.x, bbox.min.y, bbox.max.z),
  152.                              D3DXVECTOR3(bbox.max.x, bbox.min.y, bbox.min.z), 
  153.                              D3DXVECTOR3(bbox.min.x, bbox.max.y, bbox.max.z), 
  154.                              D3DXVECTOR3(bbox.min.x, bbox.max.y, bbox.min.z), 
  155.                              D3DXVECTOR3(bbox.min.x, bbox.min.y, bbox.max.z), 
  156.                              D3DXVECTOR3(bbox.min.x, bbox.min.y, bbox.min.z)};
  157.  
  158.     // Find the max and min points of these
  159.     // 8 offests points in screen space
  160.     INTPOINT pmax(-10000, -10000), pmin(10000,10000);
  161.  
  162.     for(int i=0;i<8;i++)
  163.     {
  164.         INTPOINT screenPos = GetScreenPos(corners[i], m_pDevice);
  165.  
  166.         if(screenPos.x > pmax.x)pmax.x = screenPos.x;
  167.         if(screenPos.y > pmax.y)pmax.y = screenPos.y;
  168.         if(screenPos.x < pmin.x)pmin.x = screenPos.x;
  169.         if(screenPos.y < pmin.y)pmin.y = screenPos.y;        
  170.     }
  171.  
  172.     RECT scr = {-20, -20, 820, 620};
  173.  
  174.     // Check that the max and min point is within our viewport boundaries
  175.     if(pmax.inRect(scr) || pmin.inRect(scr))
  176.     {
  177.         float s = (pmax.x - pmin.x) / 3.0f;
  178.         if((pmax.y - pmin.y) < (pmax.x - pmin.x))s = (pmax.y - pmin.y) / 3.0f;
  179.  
  180.         D3DXVECTOR2 corner1[] = {D3DXVECTOR2(pmin.x, pmin.y + s), D3DXVECTOR2(pmin.x, pmin.y), D3DXVECTOR2(pmin.x + s, pmin.y)};
  181.         D3DXVECTOR2 corner2[] = {D3DXVECTOR2(pmax.x - s, pmin.y), D3DXVECTOR2(pmax.x, pmin.y), D3DXVECTOR2(pmax.x, pmin.y + s)};
  182.         D3DXVECTOR2 corner3[] = {D3DXVECTOR2(pmax.x, pmax.y - s), D3DXVECTOR2(pmax.x, pmax.y), D3DXVECTOR2(pmax.x - s, pmax.y)};
  183.         D3DXVECTOR2 corner4[] = {D3DXVECTOR2(pmin.x + s, pmax.y), D3DXVECTOR2(pmin.x, pmax.y), D3DXVECTOR2(pmin.x, pmax.y - s)};
  184.  
  185.         //Draw the 4 corners
  186.         if(line != NULL)
  187.         {
  188.             line->SetWidth(2.0f);
  189.             line->Begin();
  190.             line->Draw(corner1, 3, 0xffffffff); 
  191.             line->Draw(corner2, 3, 0xffffffff); 
  192.             line->Draw(corner3, 3, 0xffffffff); 
  193.             line->Draw(corner4, 3, 0xffffffff); 
  194.             line->End();
  195.         }
  196.     }
  197. }
  198.  
  199. void MAPOBJECT::RenderSightMesh()
  200. {
  201.     if(m_pDevice == NULL || sightTexture == NULL || sightMesh == NULL)return;
  202.  
  203.     //Set world transformation matrix
  204.     D3DXMATRIX world, pos, sca;
  205.  
  206.     //Position the mesh at the center of the map object
  207.     D3DXMatrixTranslation(&pos, m_position.x, m_position.y, m_position.z);
  208.  
  209.     //Scale the mesh to the sight radius of the mapobject (XZ plane)
  210.     D3DXMatrixScaling(&sca, m_sightRadius, 1.0f, m_sightRadius);
  211.  
  212.     D3DXMatrixMultiply(&world, &sca, &pos);
  213.     m_pDevice->SetTransform(D3DTS_WORLD, &world);
  214.  
  215.     //Set texture and material
  216.     m_pDevice->SetTexture(0, sightTexture);
  217.     m_pDevice->SetMaterial(&sightMtrl);
  218.  
  219.     //Draw the sight mesh
  220.     sightMesh->DrawSubset(0);
  221. }